package main

import (
	"context"
	"log/slog"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	route "gitee.com/jiebaiyou/formflow/api/route"
	"gitee.com/jiebaiyou/formflow/bootstrap"
	"gitee.com/jiebaiyou/formflow/pkg/storage/redis"
	"gitee.com/jiebaiyou/formflow/pkg/storage/sqlite"
	"github.com/gin-gonic/gin"
)

// main 是应用程序的入口点, 负责初始化和启动整个后端服务
func main() {
	// 初始化应用程序, 加载配置和依赖项
	app := bootstrap.App()

	// 获取环境配置, 包括服务器地址、数据库设置、令牌密钥等
	env := app.Config

	// 获取SQLite数据库连接
	db := app.DB
	// 确保在程序结束时关闭数据库连接
	defer app.CloseDBConnection()

	// 获取Redis数据库连接并选择特定数据库
	cache := app.Redis.Database()
	// 确保在程序结束时关闭Redis连接
	defer app.CloseRedisConnection()

	// 启动HTTP服务器
	startHTTPServer(env, db, cache)
}

// startHTTPServer 启动HTTP服务器
func startHTTPServer(env *bootstrap.Config, db sqlite.DB, cache redis.Database) {
	// 设置Gin工作模式, 并创建Gin引擎
	if !env.BASE.DEBUG {
		gin.SetMode(gin.ReleaseMode)
	}
	engine := gin.New()

	// 设置上下文超时时间, 控制请求处理的最大等待时间
	timeout := time.Duration(env.BASE.CONTEXT_TIMEOUT) * time.Second
	// 注册路由
	route.RegisterRoutes(env, timeout, db, cache, engine)

	// 创建HTTP服务器
	server := &http.Server{
		Addr:    env.BASE.SERVER_ADDRESS + ":" + env.BASE.SERVER_PORT,
		Handler: engine,
	}

	// 在单独的goroutine中启动服务器
	go func() {
		// 服务连接
		slog.Info("启动HTTP服务器", slog.String("address", env.BASE.SERVER_ADDRESS), slog.String("port", env.BASE.SERVER_PORT))
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			slog.Error("启动HTTP服务器错误", slog.String("error", err.Error()))
			os.Exit(1)
		}
	}()

	// 等待中断信号优雅地关闭服务器
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	slog.Info("关闭HTTP服务器...")

	// 创建一个30秒超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 优雅关闭
	if err := server.Shutdown(ctx); err != nil {
		slog.Error("关闭HTTP服务器错误", slog.String("error", err.Error()))
		os.Exit(1)
	}

	slog.Info("HTTP服务器已关闭")
}
